package com.zimin.cloud.user.biz.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zimin.cloud.mine.pojo.user.business.FollowingGroupBO;
import com.zimin.cloud.mine.pojo.user.business.UserFollowingBO;
import com.zimin.cloud.mine.pojo.user.view.FollowingGroupVO;
import com.zimin.cloud.mine.pojo.user.view.UserFollowingVO;
import com.zimin.cloud.mine.pojo.user.view.UserInfoVO;
import com.zimin.cloud.mine.pojo.user.view.UserVO;
import com.zimin.cloud.user.biz.IUserFollowingBiz;
import com.zimin.cloud.user.common.enums.FollowingGroupEnum;
import com.zimin.cloud.user.pojo.entity.FollowingGroup;
import com.zimin.cloud.user.pojo.entity.UserFollowing;
import com.zimin.cloud.user.service.IFollowingGroupService;
import com.zimin.cloud.user.service.IUserInfoService;
import com.zimin.cloud.user.service.IUserService;
import com.zimin.cloud.user.service.impl.UserFollowingServiceImpl;
import com.zimin.common.annotation.Biz;
import com.zimin.common.exception.GraceException;
import com.zimin.common.utils.BeanUtils;
import com.zimin.common.utils.ObjectUtils;
import com.zimin.shared.enums.ResponseStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * <p>
 * 用户关注表 业务对象
 * </p>
 *
 * @author zimin
 * @since 2022-06-14 15:53
 */
@Biz("userFollowingBiz")
public class UserFollowingBizImpl extends UserFollowingServiceImpl implements IUserFollowingBiz {

    @Autowired
    private IFollowingGroupService followingGroupService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IUserInfoService userInfoService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean addUserFollowings(UserFollowingBO userFollowingBO) {
        var groupId = userFollowingBO.getGroupId();
        if (ObjectUtils.isEmpty(groupId)) {
            var followingGroupVO = followingGroupService.getByType(FollowingGroupEnum.FOLLOWING_DEFAULT.getType());
            userFollowingBO.setGroupId(followingGroupVO.getId());
        } else {
            var followingGroupVO = followingGroupService.getById(groupId, FollowingGroupVO.class);
            GraceException.isNull(followingGroupVO, ResponseStatusEnum.FOLLOWING_GROUP_IS_NULL);
        }
        var followingId = userFollowingBO.getFollowingId();
        var user = userService.getById(followingId, UserVO.class);
        GraceException.isNull(user, ResponseStatusEnum.FOLLOWING_USER_IS_NULL);
        super.remove(Wrappers.<UserFollowing>lambdaQuery().eq(UserFollowing::getUserId, user.getId()).eq(UserFollowing::getFollowingId, followingId));
        return super.save(BeanUtils.coverClass(userFollowingBO, UserFollowing.class));
    }

    @Override
    public List<FollowingGroupVO> getUserFollowing(String userId) {
        var list = super.getUserFollowings(userId);
        if (ObjectUtils.isEmpty(list)) {
            return List.of();
        }
        var followingIdSet = list.parallelStream().map(UserFollowingVO::getFollowingId).collect(Collectors.toSet());
        if (ObjectUtils.isEmpty(followingIdSet)) {
            return List.of();
        }
        var userInfoList = userInfoService.getUserInfoByUserIds(followingIdSet);
        if (ObjectUtils.isEmpty(userInfoList)) {
            return List.of();
        }
        var userInfoMap = userInfoList.parallelStream().collect(Collectors.toMap(UserInfoVO::getId, o -> o, (m1, m2) -> m1));
        list.parallelStream().forEach(userFollowingVO -> userFollowingVO.setUserInfoVO(userInfoMap.get(userFollowingVO.getFollowingId())));
        var groupList = followingGroupService.getByUserId(userId);
        var allGroup = FollowingGroupVO.builder()
                .name("全部关注")
                .followUserInfoList(userInfoList)
                .build();
        var result = new ArrayList<FollowingGroupVO>(List.of());
        result.add(allGroup);
        var userFollowingMap = list.parallelStream().collect(Collectors.toMap(UserFollowingVO::getGroupId, v -> v, (m1, m2) -> m1));
        groupList.parallelStream().forEach(followingGroup -> {
            var infoList = new ArrayList<UserInfoVO>(List.of());
            var userFollowingVO = userFollowingMap.get(followingGroup.getId());
            infoList.add(userFollowingVO.getUserInfoVO());
            followingGroup.setFollowUserInfoList(infoList);
            result.add(followingGroup);
        });
        return result;
    }

    /**
     * 1、获取当前用户的粉丝列表
     * 2、根据粉丝的用户id查询基本信息
     * 3、查询当前用户是否已经关注该粉丝
     */
    @Override
    public List<UserFollowingVO> getUserFans(String userId) {
        var fansList = super.getUserFans(userId);
        if (ObjectUtils.isEmpty(fansList)) {
            return List.of();
        }
        var fanIdSet = fansList.parallelStream().map(UserFollowingVO::getUserId).collect(Collectors.toSet());
        if (ObjectUtils.isEmpty(fanIdSet)) {
            return List.of();
        }
        var userInfoList = userInfoService.getUserInfoByUserIds(fanIdSet);
        if (ObjectUtils.isEmpty(userInfoList)) {
            return List.of();
        }
        var followingList = super.getUserFollowings(userId);
        var userInfoMap = userInfoList.parallelStream().collect(Collectors.toMap(UserInfoVO::getId, o -> o, (m1, m2) -> m1));
        var userFollowingMap = followingList.parallelStream().collect(Collectors.toMap(UserFollowingVO::getFollowingId, v -> v, (m1, m2) -> m2));
        fansList.parallelStream().forEach(fan -> {
            var userInfo = userInfoMap.get(fan.getUserId());
            userInfo.setFollowed(Boolean.FALSE);
            fan.setUserInfoVO(userInfo);
            var userFollowing = userFollowingMap.get(fan.getUserId());
            if (ObjectUtils.isNotEmpty(userFollowing)) {
                userFollowing.getUserInfoVO().setFollowed(Boolean.TRUE);
            }
        });
        return fansList;
    }

    @Override
    public Boolean save(FollowingGroupBO followingGroupBO) {
        var followingGroup = BeanUtils.coverClass(followingGroupBO, FollowingGroup.class);
        return followingGroupService.save(followingGroup);
    }

    @Override
    public List<UserFollowingVO> getUserFollowingGroups(String userId) {
        return list(lambdaQuery().eq(UserFollowing::getUserId, userId), UserFollowingVO.class);
    }

    @Override
    public List<UserInfoVO> checkFollowingStatus(List<UserInfoVO> records, String userId) {
        List<UserFollowingVO> userFollowings = super.getUserFollowings(userId);
        if (ObjectUtils.isNotEmpty(userFollowings)) {
            var userFollowingMap = userFollowings.parallelStream().collect(Collectors.toMap(UserFollowingVO::getFollowingId, v -> v, (m1, m2) -> m2));
            records.parallelStream().forEach(userInfo -> {
                UserFollowingVO userFollowingVO = userFollowingMap.get(userInfo.getId());
                if (ObjectUtils.isNotEmpty(userFollowingVO)) {
                    userInfo.setFollowed(Boolean.TRUE);
                } else {
                    userInfo.setFollowed(Boolean.FALSE);
                }
            });
        }
        return records;
    }


}
